#ifndef __HDVB_STREAM_SRC_H
#define __HDVB_STREAM_SRC_H
/*
    libhdvbd - Library for building sophisticated DVB applications
    Copyright (C) 2012 Tony Houghton <h@realh.co.uk>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/* Reads chunks of stream from a receiver's dvr device and farms out
 * selected packets to the next downstream elements.
 */

#include <glib.h>

#include <hdvb/hdvb-stream-tap-iface.h>

G_BEGIN_DECLS

typedef struct _HdvbReceiver HdvbReceiver;

typedef struct _HdvbStreamSrc HdvbStreamSrc;

/* This is the buffer size used by the kernel rounded down to a
 * whole number of packets */
#define HDVB_STREAM_SRC_BUF_SIZE (8192 - 8192 % 188)

struct _HdvbStreamSrc {
    GSource gsource;
    GPollFD poll;
    GTimeVal tock;
    GStaticRecMutex lock;
    HdvbReceiver *rcv;
    GHashTable *pids;
    GList *taps;
    gulong detune_tag;
    gboolean deleting;
    int remainder;          /* How many bytes in buffer were left over
                             * from a previous read */
    gboolean synced;        /* Whether we've found a TS packet sync byte */
    guint8 buffer[HDVB_STREAM_SRC_BUF_SIZE];
};

/**
 * hdvb_stream_src_new:
 * @rcv: The receiver to stream from.
 * Returns: A new stream source.
 *
 * This should normally only be called by the receiver to create a singleton.
 */
HdvbStreamSrc *
hdvb_stream_src_new(HdvbReceiver *rcv);

/**
 * hdvb_stream_src_delete:
 * @ssrc: The stream source to delete.
 *
 * Automatically remvoes itself from its receiver.
 * Usually you won't call this, but rely on it being called by
 * hdvb_stream_src_remove_tap.
 */
void
hdvb_stream_src_delete(HdvbStreamSrc *ssrc);

/**
 * hdvb_stream_src_add_tap:
 * @ssrc: (transfer none): The stream source to tap from.
 * @tap: A new tap to read packets from the dvr. It will be reffed until
 *      removed.
 * Returns: Whether request succeeded. May fail if too many PES filters?
 */
gboolean
hdvb_stream_src_add_tap(HdvbStreamSrc *ssrc, HdvbStreamTap *tap);

/**
 * hdvb_stream_src_remove_tap:
 * @ssrc: (transfer none): The stream source to remove tap from.
 * @tap: The tap to be removed.
 *
 * When no taps are left the stream source will be destroyed.
 */
void
hdvb_stream_src_remove_tap(HdvbStreamSrc *ssrc, HdvbStreamTap *tap);


G_END_DECLS

#endif /* __HDVB_STREAM_SRC_H */
